//
//  TSBugReuseTableViewController2.m
//  TSDemo_List
//
//  Created by qian on 2021/2/23.
//

#import "TSBugReuseTableViewController2.h"
#import <CQDemoKit/CJUIKitToastUtil.h>
#import <CQDemoKit/CQTSNetImagesUtil.h>
#import <CQDemoKit/CQTSButtonFactory.h>
#import <CQDemoKit/CQTSContainerViewFactory.h>

#import "TSImageReloadCollectionView.h"
#import "UIViewController+TSBug.h"

#import "TSBugReuseTableViewCell.h"


static CGFloat kCellHeight = 100;
static NSString *kImageUrl1 = @"https://img.tupianzj.com/uploads/200601/30-200601091404506.jpg";
static NSString *kImageUrl2 = @"https://img.tupianzj.com/uploads/allimg/202103/9999/6aa4fd2cd9.jpg";

@interface TSBugReuseTableViewController2 () <UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSMutableArray<CQTSNetImageDataModel *> *dataModels;/**< 数据源 */

@property (nonatomic, assign, readonly) BOOL fixBug;    /**< 是否修复bug（默认否） */

@end

@implementation TSBugReuseTableViewController2

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.navigationItem.title = @"Cell重用导致的图片错乱";
    
    UIButton *bugStateButton = [CQTSButtonFactory bugButtonWithFixBugHandle:^{
        [self fixBug:NO];
    } reproduceBugHandle:^{
        [self fixBug:YES];
    }];
    [self.view addSubview:bugStateButton];
    [bugStateButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(self.mas_topLayoutGuide).mas_offset(10);
        make.left.mas_equalTo(20);
        make.centerX.mas_equalTo(self.view);
        make.height.mas_equalTo(44);
    }];
    
    
    UILabel *knowledgeLabel = [self knowledgeLabel];
    knowledgeLabel.text = @"UI结构：\n\
    1、【第一个和第二个cell】的图片是image1，其他都是image2\n\
    2、滚动到后面再滚动回来，会发生【第一个和第二个cell】重用了后面的cell。\n\
    3、当【第一个和第二个cell】重用到使用 image2 的 cell的时候，虽然你想让【第一个和第二个cell】正确显示 image1，但由于重用后面cell的任务也会被重用，又由于已经模拟使得image2 返回得更慢，导致【不处理的话必定返回错乱】";
    [self.view addSubview:knowledgeLabel];
    [knowledgeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(20);
        make.centerX.mas_equalTo(self.view);
        make.top.mas_equalTo(bugStateButton.mas_bottom).mas_offset(10);
        //make.height.mas_equalTo(160);
    }];
    
    
    
    UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
    [tableView registerClass:[TSBugReuseTableViewCell class] forCellReuseIdentifier:@"cell"];
    tableView.dataSource = self;
    tableView.delegate = self;
    [self.view addSubview:tableView];
    [tableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(knowledgeLabel.mas_bottom).mas_offset(10);
        make.left.right.mas_equalTo(self.view);
        //make.bottom.mas_equalTo(self.view).mas_offset(-100);
        make.height.mas_equalTo(4*kCellHeight);
    }];
    self.tableView = tableView;
    
    NSMutableArray<CQTSNetImageDataModel *> *dataModels = [[NSMutableArray alloc] init];
    NSInteger imageCount = 100;
    for (NSInteger i = 0; i < imageCount; i++) {
        CQTSNetImageDataModel *dataModel = [[CQTSNetImageDataModel alloc] init];
        if (i < 2) {
            dataModel.imageUrl = kImageUrl1;
        } else {
            dataModel.imageUrl = kImageUrl2;
        }
        dataModel.name = [NSString stringWithFormat:@"%zd", i];
       
        dataModel.badgeCount = i;
        [dataModels addObject:dataModel];
    }
    self.dataModels = dataModels;
    [self.tableView reloadData];
    
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    self.queue = queue;
}

#pragma mark - Event
/*
 *  是否要修复bug
 *
 *  @param shouldFixBug 是否要修复bug（YES:修复bug; NO:重现bug）
 */
- (void)fixBug:(BOOL)shouldFixBug {
    _fixBug = shouldFixBug;
}


#pragma mark - UITableViewDataSource & UITableViewDelegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSInteger cellCount = self.dataModels.count;
    return cellCount;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return kCellHeight;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TSBugReuseTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    
    CQTSNetImageDataModel *dataModel = [self.dataModels objectAtIndex:indexPath.item];
    NSString *title = [NSString stringWithFormat:@"%zd", indexPath.row];
    cell.textLabel.text = dataModel.name;
    // image
//    UIImage *placeholderImage = nil;
//        cell.backgroundImageView.image = placeholderImage;
    
    // 方法2：
    __weak typeof(cell)weakCell = cell;
    NSString *imageUrl = dataModel.imageUrl;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        if (cell.op1) {
            [cell.op1 cancel];
        }

        NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
            //NSLog(@"1----%@", [NSThread currentThread]);
            CGFloat delay = 0;
            // 模拟使得 kImageUrl2 的图片更慢返回，以此重现当重用到使用 kImageUrl2 的 cell的时候，虽然该cell是要显示 kImageUrl1，但由于 kImageUrl2 返回得更慢，导致返回错乱
            if ([imageUrl isEqualToString:kImageUrl2]) {
                delay = 0.5;
            } else {
                delay = 0;
            }
            [NSThread sleepForTimeInterval:delay];
            NSURL *imageURL = [NSURL URLWithString:imageUrl];
            UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageURL]];

            dispatch_async(dispatch_get_main_queue(), ^{
                cell.backgroundImageView.image = image;
            });
        }];

        [self.queue addOperation:op1];


        cell.op1 = op1;
    });
    
    
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
    NSLog(@"点击了%zd-%zd", indexPath.section, indexPath.row);
}


/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
